package com.sun;

/**
 * https://leetcode.cn/problems/string-to-integer-atoi/
 * 请你来实现一个myAtoi(string s)函数，使其能将字符串转换成一个 32 位有符号整数（类似 C/C++ 中的 atoi 函数）。
 *
 * 函数myAtoi(string s) 的算法如下：
 *
 * 读入字符串并丢弃无用的前导空格
 * 检查下一个字符（假设还未到字符末尾）为正还是负号，读取该字符（如果有）。 确定最终结果是负数还是正数。 如果两者都不存在，则假定结果为正。
 * 读入下一个字符，直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
 * 将前面步骤读入的这些数字转换为整数（即，"123" -> 123， "0032" -> 32）。如果没有读入数字，则整数为 0 。必要时更改符号（从步骤 2 开始）。
 * 如果整数数超过 32 位有符号整数范围 [−2^31, 2^31-1] ，需要截断这个整数，使其保持在这个范围内。具体来说，小于 −2^31 的整数应该被固定为 −2^31 ，大于 2^31− 1 的整数应该被固定为 2^31− 1 。
 * 返回整数作为最终结果。
 * 注意：
 * 本题中的空白字符只包括空格字符 ' ' 。
 * 除前导空格或数字后的其余字符串外，请勿忽略 任何其他字符。
 */
public class Test8StringToInt {
    public static void main(String[] args) {
        System.out.println("测试1："+Character.digit('5',10));
        System.out.println("测试2："+Integer.valueOf("+11"));
        System.out.println("测试3："+(1+'1'));//自动类型转换 ’1‘转换成int 然后 1 + 49 因为1的ASCII码为49
        System.out.println("测试4："+(1+'1'-'0'));//1 + 49 因为1的ASCII码为49
        System.out.println("测试5："+"1"+'1');
        System.out.println("测试6："+1+'1');
        System.out.println("    sdfsa".trim());
        int res = myAtoi3("42");
        System.out.println("res="+res);
    }

    /**
     * 自己参考Integer.valueof()
     */
    public static int myAtoi1(String s) {
        if (s == null || s.equals("")){
            return 0;
        }
        s = s.trim();
        if (s == null || s.equals("")){
            return 0;
        }
        int i = 0, len = s.length(),radix = 10;
        boolean negative = false;
        int limit = Integer.MAX_VALUE;
        char firstChar = s.charAt(i);
        if(firstChar < '0'){
            if (firstChar == '-'){
                negative = true;
                limit = Integer.MIN_VALUE;
            }else if (firstChar != '+'){
                return 0;
            }
            if (len == 1){
                return 0;
            }
            i++;
        }

        int multmin = limit/radix;
        int result = 0;
        while (i < len){
            int digit = Character.digit(s.charAt(i++), 10);
            if (digit < 0){
                return negative ? result : -result;
            }
            if ( result < multmin){
                return negative ? limit : -limit;
            }
            result *= radix;
            if (result < limit+digit){
                return negative ? limit : -limit;
            }
            result -= digit;
        }
        return negative ? result : -result;
    }

    /**
     * 改写Integer.valueof的逻辑:
     *  改写不了，因为Interge.Min_VALUE转换不成正数；
     *  解决办法：将limit定义为long类型
     */
    public  static int myAtoi2(String s){
        if(s == null || s.equals("")){
            return 0;
        }
        s = s.trim();
        if(s.equals("")){
            return 0;
        }
        int i = 0,len = s.length();
        long limit = Integer.MAX_VALUE;
        boolean isnegative = false;
        if(!Character.isDigit(s.charAt(i))){
            if (s.charAt(i) == '-'){
                isnegative = true;
                limit = 0l-Integer.MIN_VALUE;
            }else if (s.charAt(i) != '+'){
                return 0;
            }
            i++;
            if (len == 1){
                return 0;
            }
        }
        int result = 0;
        while (i < len){
            int digit = Character.digit(s.charAt(i++), 10);
            if(digit < 0){
                return isnegative ? -result :  result;
            }
            if (result>limit/10 || result + digit > limit){
                return isnegative ? Integer.MIN_VALUE : Integer.MIN_VALUE;
            }
            result = result * 10 + digit;
        }
        return isnegative ? -result : result;
    }

    /**
     *力扣评论
     */
    public static int myAtoi3(String s){
        s = s.trim();
        if(s.length() == 0) return 0;
        if(!Character.isDigit(s.charAt(0)) && s.charAt(0) != '-' && s.charAt(0) != '+') return 0;
        boolean negative = s.charAt(0) == '-';
        int i = Character.isDigit(s.charAt(0)) ? 0 : 1;
        long result = 0l;
        while (i < s.length() && Character.isDigit(s.charAt(i))){
            result = result * 10 + (s.charAt(i++)-'0');
            if(negative && result > 1L + Integer.MAX_VALUE){
                return Integer.MIN_VALUE;
            }
            if (!negative && result > Integer.MAX_VALUE){
                return Integer.MAX_VALUE;
            }
        }
        return negative ? (int)-result : (int)result;
    }

}
